package com.group2.bankonline.controller;

import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teautil.models.RuntimeOptions;
import com.group2.bankonline.pojo.Mobile;
import com.group2.bankonline.pojo.Personinfo;
import com.group2.bankonline.service.IMobileService;
import com.group2.bankonline.service.IPersoninfoService;
import com.group2.bankonline.utils.JsonResult;
import com.group2.bankonline.utils.MyJWT;
import com.group2.bankonline.utils.Sample;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Objects;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import com.group2.bankonline.config.MyRedisConfig;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author syf
 * @since 2024-07-11
 */
@RestController
@RequestMapping("/mobilebank/personinfo")
public class PersoninfoController {
    @Autowired
    private IPersoninfoService iPersoninfoService;

    @Autowired
    private IMobileService iMobileService;

    @Resource
    private RedisTemplate redisTemplate;

    /*
    * 登录逻辑：
    * 1. 获取手机号和密码
    * 2. 查询根据手机和密码获取用户信息
    * 3. 登录成功，获取相应信息，生成token并返回响应类包装结果
    * 4. 登录失败，返回响应类结果
    * */
    @PostMapping("/login")
    public JsonResult login(@RequestBody Mobile mobile) {
        Personinfo personinfo = iPersoninfoService.getByTelAndPwd(mobile.getTelephone(), mobile.getPassword());
            if (personinfo != null) {
                // 生成token
                String token = MyJWT.getToken(personinfo);
                // 将手机号和token存入redis
                mobile.setPassword("null");
                redisTemplate.opsForValue().set(token,mobile);
                return new JsonResult(true, personinfo, token);
            } else {
                return new JsonResult(false, "用户名或密码不正确");
            }
        }

    /*
    * 退出逻辑:
    * 1. 获取前端返回的token
    * 2. 调用logout方法
    * 3. 在redis库中删除对应的键值对
    * */
    @PostMapping("/logout")
    public JsonResult logout(@RequestBody HashMap<String,String> map){
        iPersoninfoService.logout(map.get("token"));
        return new JsonResult(true,"退出成功");
    }

    /*
    * 注册逻辑：
    * 1. 获取用户注册的手机号和密码
    * 2. 判断当前手机号是否已被注册
    * 3. 若已注册则报错，并要求重新注册
    * 4. 若未注册，则查询用户信息表，判断用户是否已在线下办卡，是否有手机号等信息存储
    * 5. 用户信息表无信息，则报错，并提醒用户前往线下办卡
    * 6. 用户信息表有信息，则在mobile表中进行数据添加，并生成token
    *
    * ps:接口测试中选择x-www-form-urlencoded:可以将表单数据编码成键值对形式，发送到服务器端
    * */
   @PostMapping("/register")
    public JsonResult register(@RequestBody HashMap<String ,Object> map) {

        Mobile registermobile = iMobileService.getByTel(map.get("telephone").toString() );
        if (registermobile != null) {
            return new JsonResult(false, "该号码已被注册，请重新注册");
        }
        Personinfo personinfo = iPersoninfoService.getByTel(map.get("telephone").toString());
        if (personinfo == null) {
            return new JsonResult(false, "手机信息不存在，请前往线下办理业务");
        }
        if (!Objects.equals(map.get("checkpwd").toString(),map.get("pwd").toString() )) {
            return new JsonResult(false, "两次密码不一致，请重新输入密码");
        }
        if (!Objects.equals(map.get("verify").toString(), "1013")) {
            return new JsonResult(false,"验证码错误，请重新进行验证");
        }
        Mobile mobile = new Mobile();
        mobile.setTelephone(map.get("telephone").toString());
        mobile.setPassword(map.get("pwd").toString());
        iMobileService.save(mobile);
        personinfo = iPersoninfoService.getByTelAndPwd(map.get("telephone").toString(),map.get("pwd").toString());
        String token = MyJWT.getToken(personinfo);
        return new JsonResult(true, personinfo, token);
    }

    /*
    * 个人信息查询：
    * 1.接收前端传来的token值
    * 2.检查token是否有效
    * 3.返回查询结果
    * */
    @RequestMapping("/selectAll")
    public JsonResult selectAll(@RequestParam String token) {
        try {
            if (MyJWT.checkToken(token)) {
                String realname = MyJWT.getNameByToken(token);
                Personinfo personinfo = iPersoninfoService.getByRealName(realname);
                return new JsonResult(true, personinfo, "查询成功");
            } else {
                return new JsonResult(false, "无效的token");
            }
        } catch (Exception e) {
            // 处理异常并返回错误信息
            return new JsonResult(false, "查询过程中发生错误: " + e.getMessage());
        }
    }

    /*
    * 个人信息修改：（信息查询成功才能显示信息供用户修改）
    * 1.接收前端传来的表单 (需带有姓名作为后续更新的依据，且仅生日、地址、邮箱可供修改，其余数据因线下注册已确定而不可修改)
    * 2.更新用户个人信息
    * 3.返回更新结果
    * */
    @PostMapping("/updateinfo")
    public JsonResult updateinfo(@RequestBody Personinfo personinfo){
        int count = iPersoninfoService.updateinfo(personinfo);
        if (count>0){
            return new JsonResult(true,"修改成功");
        }else {
            return new JsonResult(false,"修改失败，请重新修改");
        }
    }

    /*
    * 短信验证：
    * 1.创建阿里云短信服务的客户端
    * 2.创建发送短信的请求
    * 3.发送短信
    * 4.输出响应结果
    * */
    @GetMapping("/verify")
    public JsonResult verify() throws Exception {
        // 创建阿里云短信服务的客户端
        com.aliyun.dysmsapi20170525.Client client = Sample.createClient();


        // 创建发送短信的请求
        com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
                .setSignName("阿里云短信测试")
                .setTemplateCode("SMS_154950909")
                .setPhoneNumbers("15282452992")  //仅可使用绑定后的测试手机号码
                .setTemplateParam("{\"code\":\"1013\"}");  //可设置后自动生成验证码
        RuntimeOptions runtime = new RuntimeOptions();

        // 发送短信
        SendSmsResponse response = client.sendSms(sendSmsRequest);
        // 输出响应结果
        System.out.println(response.getBody());
        // 也可以选择使用 sendSmsWithOptions 方法
        client.sendSmsWithOptions(sendSmsRequest, runtime);

        return new JsonResult(true, "验证码发送成功");
    }
}
